from flask import request, jsonify, g
from info.utils.common import login_user_data
from info import constants
from info.models import User, News, Category
from info.utils.response_code import RET
from . import index_bp
from flask import render_template, current_app, session


# 返回web的头像图标
@index_bp.route('/favicon.ico')
def favicon():
    """返回项目图标"""
    # send_static_file: 将static中的静态文件发送给浏览器
    return current_app.send_static_file("news/favicon.ico")


@index_bp.route('/')
@login_user_data
def index():
    """这个是返回主页, 切换用户的登陆登出的状态
    """
    # ------- 1.查询用户信息将用户信息通过模板带回进行展示--------
    # 在session里面取获取user_id的值
    # user_id = session.get('user_id')
    # # 这边先在外部给它定义一个变量先 下面两个函数都是局部变量, 如果前面没有给他们一个变量的话 后面两个会被认为不是同一个变量
    # user = None
    # if user_id:
    #     try:
    #         # 先去查询获取user_id
    #         user = User.query.get(user_id)
    #     except Exception as e:
    #         current_app.logger.error(e)
    # 封装成了login_user_data
    user = g.user

    # to_dict()方法是在User里面封装好的一个方法, 能获取user这个实例对象(就是用户传过来的user_id所对应的实例对象)的属性

    # ------- 2.查询新闻的点击排行数据进行展示--------
    news_model_list = None
    try:
        news_model_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)

    news_dict_list = []
    # 取遍历获取news_model_list里面的数值, 再用具体数值取获取对应的具体信息
    for news in news_model_list if news_model_list else []:
        news_dict_list.append(news.to_dict())
    # ------- 3.查询新闻的分类数据进行展示--------
    categories = []
    try:
        categories = Category.query.all()
    except Exception as e:
        current_app.logger.error(e)
    category_dict_list = []
    # 对象模型列表转字典列表
    for category in categories if categories else []:
        category_dict_list.append(category.to_dict())

    data = {"user_info": user.to_dict() if user else None,
            "newsClicksList": news_dict_list,
            'categories':category_dict_list
            }
    return render_template('index.html', data=data)


@index_bp.route('/news_list')
def get_news_list():
    """新闻列表的实现 用的是get请求"""
    """
    1.获取参数
    1.1 cid分类id page当前页码（默认展示第一页） per_page当前页展示多少条数据（默认展示10条新闻）
    2.判断参数
    2.1非空判断
    2.2 对数据类型进行校验判断
    3.逻辑处理
    3.3 根据上传参数进行数据库分页查询
    3.4 将数据转换成dict对象给前端使用
    4.返回值处理
    """
    # 1.1 cid分类id page当前页码（默认展示第一页） per_page当前页展示多少条数据（默认展示10条新闻）
    cid = request.args.get('cid')
    per_page = request.args.get('per_page', constants.OTHER_NEWS_PAGE_MAX_COUNT)
    page = request.args.get('page', 1)

    # 2.1非空判断
    if not all([cid, page, per_page]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 2.2 对数据类型进行校验判断
    try:
        cid = int(cid)
        page = int(page)
        per_page = int(per_page)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg="数据类型错误")

    # 3.3 根据上传参数进行数据库分页查询
    # 最新的新闻 不需要根据cid来查询只需要根据创建时间来查询
    # 3. 查询数据并分页
    filters = [News.status == 0]
    # 如果分类id不为0，那么添加分类id的过滤
    # 将查询条件添加到filter列表中
    if cid != 1:
        filters.append(News.category_id == cid)

    try:
        # 3.3 根据上传参数进行数据库分页查询
        paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page, per_page, False)

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻列表数据异常")

    # 当前页码所有数据
    item = paginate.items

    # 当前页码
    current_page = paginate.page
    # 总页数
    total_page = paginate.pages

    # 3.4 将数据转换成dict对象给前端使用
    newsList = []
    # 遍历items模型列表获取个每一个模型进而转换成字典添加在newsList中

    for news in item if item else []:
        newsList.append(news.to_dict())

    data = {
        "newsList": newsList,
        "current_page": current_page,
        "total_page": total_page
    }

    return jsonify(errno=RET.OK, errmsg="查询新闻list数据成功", data=data)

